﻿// (c) Norbert Huffschmid
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.

using System;
using System.Windows;
using System.Collections;
using System.Collections.Specialized;
using System.Windows.Input;
using System.ComponentModel;

namespace SpinDotters.Core
{
    public class DomainUpDown : UpDownBase, INotifyPropertyChanged
    {
        /// <summary>
        /// Notifies listeners that a property value has changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Event fired when spinning is done and selected item has changed.
        /// </summary>
        [Category("SpinDotters")]
        public new event EventHandler SelectedItemChanged;


        /// <summary>
        /// Gets or sets the index of the selected item.
        /// </summary>
        [Category("SpinDotters")]
        public new int SelectedIndex
        {
            get
            {
                return base.SelectedIndex;
            }

            set
            {
                base.SelectedIndex = value;
            }
        }

        /// <summary>
        /// Gets or sets the selected item.
        /// </summary>
        [Category("SpinDotters")]
        public object SelectedItem
        {
            get
            {
                if (this.Items.Count == 0)
                    return null;
                else
                    return this.Items[this.SelectedIndex];
            }

            set
            {
                if (SelectedItem != null)
                {
                    if (this.Items.Contains(value))
                    {
                        this.SelectedIndex = this.Items.IndexOf(value);
                    }
                    else
                    {
                        this.Items.Add(value);
                        this.SelectedIndex = this.Items.Count - 1;
                    }
                }
            }
        }

        /// <summary>
        /// Gets the item list.
        /// </summary>
        [Category("SpinDotters")]
        public new IList Items
        {
            get
            {
                return base.Items;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public DomainUpDown()
        {
            base.SelectedItemChanged +=
                new RoutedEventHandler(DomainUpDown_SelectedItemChanged);
        }

        protected virtual void OnPropertyChanged(String info)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        protected virtual void OnSelectedItemChanged()
        {
            if (SelectedItemChanged != null)
                SelectedItemChanged(this, EventArgs.Empty);
        }

        /// <summary>
        /// Determine index from key
        /// </summary>
        /// <param name="key">Key parameter as delivered in KeyEventArgs</param>
        /// <returns>Index of matching item or -1 in case of no matching item</returns>
        protected override int DetermineIndexFromKey(Key key)
        {
            string keyString = key.ToString();

            // special handling for space key
            if (key == Key.Space)
                keyString = " ";

            // special handling for number keys
            if ((keyString.Length == 2) && keyString.Substring(0, 1).Equals("D"))
                keyString = keyString.Remove(0, 1);

            if (keyString.Length != 1)
                return -1; // invalid key
            
            foreach (object item in this.Items)
            {
                if (item.ToString().Substring(0, 1) == keyString.ToUpper())
                    return (this.Items.IndexOf(item)); // item found
            }

            return -1; // no matching item found
        }

        private void DomainUpDown_SelectedItemChanged(object sender, RoutedEventArgs e)
        {
            OnSelectedItemChanged();
            OnPropertyChanged("SelectedIndex");
            OnPropertyChanged("SelectedItem");
        }
    }
}
